package service

import (
	"duoke/context"
	"duoke/model"
	"duoke/tables"
	"duoke/utils/gconv"
	"duoke/utils/orm"
	"duoke/utils/storage"
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/mitchellh/mapstructure"
)

var Upload = new(uploadService)

type uploadService struct{}

// 文件保存
func (s *uploadService) Save(c *gin.Context, file storage.StructFile) error {
	accountR, _ := Request.Account(c)
	upload := new(tables.Upload)
	upload.GroupId = file.GroupId
	upload.Size = gconv.Int(file.Size)
	upload.Path = file.Path
	upload.Url = file.Url
	upload.Name = file.Name
	upload.Url = file.Url
	upload.Type = file.Type
	upload.Suffix = file.Suffix
	upload.OriginalName = file.OriginalName
	upload.Acid = accountR.Id

	upload.App = context.Global.App
	upload.Role = "account"
	upload.Storage = "local"
	_, err := orm.Db.Insert(upload)
	return err
}

// 文件列表
func (s *uploadService) List(c *gin.Context, req model.ReqList) ([]tables.Upload, int64, error) {
	accountR, _ := Request.Account(c)
	// 分页
	offset := (req.PageNo - 1) * req.PageSize
	uploadList := make([]tables.Upload, 0)
	total, err := orm.Db.Where("acid =? and group_id =? and type like '"+req.Type+"%'", accountR.Id, req.GroupId).
		Desc("id").Limit(req.PageSize, offset).
		FindAndCount(&uploadList)
	if err != nil {
		return nil, 0, err
	}
	return uploadList, total, nil
}

// 删除
func (s *uploadService) Del(c *gin.Context, req model.ReqUploadDel, setting *storage.StructConfig) error {
	accountR, _ := Request.Account(c)
	// 查询文件
	uploadList := make([]tables.Upload, 0)
	err := orm.Db.Where("acid =?", accountR.Id).In("id", req.Ids).Find(&uploadList)
	if err != nil {
		return err
	}
	// 文件key
	var keys []string
	for _, value := range uploadList {
		keys = append(keys, value.Path)
	}
	// 执行删除
	if setting.Type == "local" {
		// 本地保存
		for _, value := range uploadList {
			// 删除文件
			_ = storage.Local.Del(value.Path)
		}
	} else if setting.Type == "qiniu" {
		// 七牛云
		err = storage.Qiniu.Del(setting, keys)
		if err != nil {
			return err
		}
	} else if setting.Type == "cos" {
		// 腾讯云
		err = storage.Cos.Del(setting, keys)
		if err != nil {
			return err
		}
	} else if setting.Type == "oss" {
		// 阿里云
		err = storage.Oss.Del(setting, keys)
		if err != nil {
			return err
		}
	} else {
		return errors.New("请先配置上传设置")
	}
	// 删除数据
	_, err = orm.Db.Where("acid =?", accountR.Id).In("id", req.Ids).Delete(new(tables.Upload))
	if err != nil {
		return err
	}
	return nil
}

// 保存分组
func (s *uploadService) GroupSave(c *gin.Context, data model.ReqUploadGroup) error {
	accountR, _ := Request.Account(c)
	group := new(tables.UploadGroup)
	group.Name = data.Name
	var err error
	if data.Id != 0 {
		_, err = orm.Db.ID(data.Id).Cols("name").Update(group)
	} else {
		group.Acid = accountR.Id
		_, err = orm.Db.Insert(group)
	}
	return err
}

// 分组列表
func (s *uploadService) GroupList(c *gin.Context) ([]tables.UploadGroup, error) {
	accountR, _ := Request.Account(c)
	groupList := make([]tables.UploadGroup, 0)
	err := orm.Db.Where("acid =?", accountR.Id).Asc("id").Find(&groupList)
	if err != nil {
		return nil, err
	}
	return groupList, nil
}

// 分组删除
func (s *uploadService) GroupDel(c *gin.Context, id int) error {
	accountR, _ := Request.Account(c)
	// 先把该分组下的所有文件移动至默认分组
	upload := new(tables.Upload)
	upload.GroupId = 0
	_, err := orm.Db.Where("acid =?", accountR.Id).Where("group_id =?", id).Cols("group_id").Update(upload)
	if err != nil {
		return err
	}
	// 执行删除
	group := new(tables.UploadGroup)
	affected, err := orm.Db.ID(id).Delete(group)
	if err != nil {
		return err
	}
	if affected == 0 {
		return errors.New("删除异常")
	}
	return nil
}

// 分组移动
func (s *uploadService) GroupMove(c *gin.Context, req model.ReqUploadGroupMove) error {
	accountR, _ := Request.Account(c)
	upload := new(tables.Upload)
	upload.GroupId = req.GroupId
	_, err := orm.Db.Where("acid =?", accountR.Id).In("id", req.Ids).Cols("group_id").Update(upload)
	return err
}

// 获取上传设置
func (s *uploadService) Setting(c *gin.Context) (*storage.StructConfig, error) {
	accountR, _ := Request.Account(c)
	account, err := Account.GetById(accountR.Id, "id,use_storage_acid")
	if err != nil {
		return nil, err
	}
	var configMap map[string]interface{}
	if account.UseStorageAcid > 0 {
		configMap, err = AccountSetting.InfoById(account.UseStorageAcid, "upload")
		if err != nil {
			return nil, err
		}
	} else {
		configMap, err = AccountSetting.Info(c, "upload")
		if err != nil {
			return nil, err
		}
	}
	if configMap["type"] == "" || configMap["type"] == nil {
		return nil, errors.New("请先配置储存设置")
	}
	var storageConfig storage.StructConfig
	err = mapstructure.Decode(configMap, &storageConfig)
	if err != nil {
		return nil, err
	}
	return &storageConfig, nil
}
